package com.example.demo.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.example.demo.groovy.GroovyUtilsFactory;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.InvokerHelper;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.File;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author: wn
 * @Date: 2021/8/20 15:08
 * @Version 1.0
 * @Note
 */
public class Test {

    private static double EARTH_RADIUS = 6378.137;// 单位千米

    /**
     * 角度弧度计算公式 rad:(). <br/>
     *
     * 360度=2π π=Math.PI
     *
     * x度 = x*π/360 弧度
     *
     * @author chiwei
     * @param degree
     * @return
     * @since JDK 1.6
     */
    private static double getRadian(double degree) {
        return degree * Math.PI / 180.0;
    }

    /**
     * 依据经纬度计算两点之间的距离 GetDistance:(). <br/>
     *
     *
     * @author chiwei
     * @param lat1
     *            1点的纬度
     * @param lng1
     *            1点的经度
     * @param lat2
     *            2点的纬度
     * @param lng2
     *            2点的经度
     * @return 距离 单位 米
     * @since JDK 1.6
     */
    public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = getRadian(lat1);
        double radLat2 = getRadian(lat2);
        double a = radLat1 - radLat2;// 两点纬度差
        double b = getRadian(lng1) - getRadian(lng2);// 两点的经度差
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1)
                * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        return s * 1000;
    }

//    public static void main(String ar[]) {
////        double distance = getDistance(38.900000, 116.397447,  39.909189, 116.397447);
////        System.out.println(distance);
//
////        for(int i = 0; i < 100; i++) {
////            String random = (int) ((Math.random() * 9 + 1) * 100000) + "";
////            System.out.println(random);
////        }
//
////        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
////        Calendar nowTime = Calendar.getInstance();
////        nowTime.add(Calendar.MINUTE, 5);
////        System.out.println(nowTime.getTime().getTime());
////
////        System.out.println(nowTime.getTime().getTime() - new Date().getTime());
//
//        //参数1为终端ID
//        //参数2为数据中心ID
////        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
////        for (int i = 0; i < 100; i++) {
////            long id = snowflake.nextId();
////            System.out.println(id);
////        }
//
//    }

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
//        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date d1=sdf.parse("2012-09-15 10:10:10");
//        Date d2=sdf.parse("2012-09-15 12:00:00");
//        System.out.println(daysBetween(d1,d2));


//        JSONObject json = new JSONObject();
//        json.put("appid", "ff402095339b57dad2b6bcf5ef7161c7");
//        long time = System.currentTimeMillis()/1000;
//        System.out.println(time);
//        json.put("timestamp", time);
//        json.put("appkey", "18a8d26c3cc3e4c4b68535dc7d55b715");
//        json.put("nonce", "wqeqweqw");
//
//        String signEcrypt = buildSign(json);
//        System.out.println(signEcrypt);

//        System.out.println(SecureUtil.generateKey("123"));

//        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date charingStartTime=sdf.parse("2022-06-02 11:02:52");
//        Date d2=sdf.parse("2022-06-02 11:08:00");
//        Long charingTimeMin = (d2.getTime() - charingStartTime.getTime()) / (1000 * 60); // 实际充电时间（分钟）
//        System.out.println(charingTimeMin);
//        BigDecimal powerPriceMin = new BigDecimal(600).divide(new BigDecimal(60),2,BigDecimal.ROUND_HALF_UP); // 计费单价（分/分钟）
//        System.out.println(powerPriceMin);
//        BigDecimal chargingAmount = powerPriceMin.multiply(new BigDecimal(charingTimeMin)).divide(new BigDecimal(100)); //充电金额（元）
//        if(new BigDecimal("0.5").compareTo(chargingAmount) <= 0 ) {
//            System.out.println(chargingAmount);
//        }

//        StringJoiner installAddress = new StringJoiner("");
//        installAddress.add("123");
//        installAddress.add("");
//        installAddress.add("erwr");
//        System.out.println(installAddress);

//        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDH2nYon2X/VJeiloSk1lMfLKKHArLC1Z9oO1Nt1+A8LtorVFmwbFx9zyXjIBsZduSp13dmfpKv4Lt89SuIX10c26WSit6tZkzqaWjkyzyk3C4qRsgUnZ6Y9UeEfcj+AvaFCOwKvMbguHeYPoy5jfHqJ30q6SNK/QCWX55cDS25mQIDAQAB";
//
//        Map<String, Object> param = new HashMap<>();
//        param.put("mobile", "15275115412");
//        param.put("orderNo", "son202208081520147310");
//        param.put("take_code", 111111);
//        System.out.println(JSON.toJSONString(param));
//        RSA rsa = new RSA(null, publicKey);
//        String encrypt = rsa.encryptBase64(JSON.toJSONString(param), KeyType.PublicKey);
//        System.out.println(encrypt);

//        Date dNow = new Date();   //当前时间
//        Date dBefore = new Date();
//        Calendar calendar = Calendar.getInstance(); //得到日历
//        calendar.setTime(dNow);//把当前时间赋给日历
//        calendar.add(Calendar.YEAR, 1);  //设置为前3月
//        dBefore = calendar.getTime();   //得到前3月的时间
//        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); //设置时间格式
//        String defaultStartDate = sdf.format(dBefore);    //格式化前3月的时间
//        LocalDate time1 = LocalDate.now();
//        Date date = Date.from(time1.atStartOfDay(ZoneId.systemDefault()).toInstant());
//        String defaultEndDate = sdf.format(date); //格式化当前时间
//        System.out.println("三个月之前时间======="+defaultStartDate);
//        System.out.println("当前时间==========="+defaultEndDate);
//
//        Date date1 = getDateBYMonths(new Date(), 10);
//        System.out.println(sdf.format(date1));

//        Date newDate = DateUtil.offset(new Date(), DateField.MONTH, -1);
//        System.out.println(newDate);
//
//        String formatDate = DateUtil.format(new Date(), "yyyy-MM");
//        System.out.println(formatDate);

//        String s = " ";
//        System.out.println(ObjectUtil.isNotEmpty(s));
//        System.out.println(StrUtil.isNotBlank(s));

//        byte[] data = "我是一段测试字符串".getBytes();
//        Sign sign = SecureUtil.sign(SignAlgorithm.SHA1withRSA);
//        //签名
//        byte[] signed = sign.sign(data);
//        //验证签名
//        boolean verify = sign.verify(data, signed);

//        ScriptEngine engine=new ScriptEngineManager().getEngineByName("JavaScript");
//        System.out.println("1+2 "+engine.eval("1+2"));
//        System.out.println("!true||false "+engine.eval("!true||false "));
//        System.out.println("1>2?true:false "+engine.eval("1>2?true:false"));

//        String script = "import cn.hutool.json.JSONUtil\n" +
//                "\n" +
//                "def handler(def values) {\n" +
//                "    // TODO\n" +
//                "    JSONUtil.parseObj(values)\n" +
//                "    log.info(values);\n" +
//                "    return values;\n" +
//                "}";
//        int num = 10000;
//        String ss  = "        {\n" +
//                "            \"ts\":1663920766884,\n" +
//                "            \"values\":{\n" +
//                "                \"app_version_name\":\"67\",\n" +
//                "                \"connectStatus\":\"1\"\n" +
//                "            }\n" +
//                "        }";
//        JSONObject json = JSONUtil.parseObj(ss);
////        json.set("aa", "aa");
////        json.set("num", 1);
//
//        GroovyUtilsFactory groovyUtilsFactory = new GroovyUtilsFactory();
//        Object s = groovyUtilsFactory.invoke(script, "handler",json.get("values"));
////        System.out.println(json.toString());
////        System.out.println(s.toString());

//        Date d = DateUtil.parse("14:00:00", "ss mm HH");
//        System.out.println(d.toString());

        long workerId;

        try {System.out.println(NetUtil.getLocalhostStr());
            // 当前机器的局域网IP
            workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr());
        } catch (Exception e) {
            workerId = NetUtil.getLocalhost().hashCode();
        }
        System.out.println(workerId);
        System.out.println(workerId % 100);
    }

    public <T> T invoke03(String scriptText, String func, Object... objs){
        Binding binding = new Binding();
        binding.setProperty("name", "Juxinli");

        GroovyShell groovyShell = new GroovyShell();
        Script script = groovyShell.parse(scriptText);
        Object result = InvokerHelper.invokeMethod(script, func, objs);
        return (T) result;
    }

    /**
     * 根据传入日期得到months个月后的日期
     * @param date
     * @param months
     * @return
     */
    private static Date getDateBYMonths(Date date, int months) {
        Calendar calendar = Calendar.getInstance(); //得到日历
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, months);
        Date dBefore = calendar.getTime();
        return dBefore;
    }

    //sign
    public static String buildSign(JSONObject json) {
        StringBuffer buffer = new StringBuffer();
        TreeMap<String, Object> treeMap = new TreeMap<String, Object>();
        for (Map.Entry<String, Object> entry : json.entrySet()) {
            if (entry.getValue() != null) {
                treeMap.put(entry.getKey(), entry.getValue());
            }
        }
        for (Map.Entry<String, Object> entry : treeMap.entrySet()) {
            if (entry.getValue() != null) {
                buffer.append(entry.getValue());
            }
        }
        System.out.println(buffer.toString());
        return SecureUtil.md5(buffer.toString()).toUpperCase();
    }

    /**
     * 计算两个日期之间相差的天数
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate,Date bdate) throws ParseException
    {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        smdate=sdf.parse(sdf.format(smdate));
        bdate=sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }
}
